#ifndef GUDB_PERF_MONITOR_H
#define GUDB_PERF_MONITOR_H

#include <stdint.h>
#include <time.h>
#include <stdbool.h>
#include "logger.h"
#include "../stats/statistics_collector.h"

#ifdef __cplusplus
extern "C" {
#endif

// Forward declarations
typedef struct statement statement_t;

// Performance monitoring configuration
typedef struct {
    uint64_t slow_query_threshold_ms;   // Slow query threshold (default: 1000ms)
    bool enable_query_logging;          // Log all queries
    bool enable_slow_query_logging;     // Log only slow queries
    bool enable_performance_metrics;    // Collect performance metrics
    bool enable_execution_plans;        // Log execution plans for slow queries
    uint32_t metrics_collection_interval_ms; // How often to collect metrics
} perf_monitor_config_t;

// Query execution context
typedef struct {
    char query_text[1024];              // SQL query text
    char query_hash[65];                // Query hash for identification
    uint64_t start_time_us;             // Start time in microseconds
    uint64_t end_time_us;               // End time in microseconds
    uint64_t rows_examined;             // Rows examined during execution
    uint64_t rows_returned;             // Rows returned to client
    uint64_t bytes_sent;                // Bytes sent to client
    char error_message[256];            // Error message if query failed
    bool has_error;                     // Whether query had an error
    const char* username;               // User who executed the query
    const char* database_name;          // Database context
} query_execution_context_t;

// System performance metrics
typedef struct {
    uint64_t queries_per_second;        // Current QPS
    uint64_t slow_queries_count;        // Number of slow queries
    uint64_t total_queries_count;       // Total queries executed
    uint64_t failed_queries_count;      // Number of failed queries
    double avg_query_time_ms;           // Average query execution time
    double max_query_time_ms;           // Maximum query execution time
    uint64_t active_connections;        // Current active connections
    uint64_t total_connections;         // Total connections since start
    uint64_t cache_hit_ratio_percent;   // Cache hit ratio
    uint64_t disk_reads_per_second;     // Disk reads/sec
    uint64_t disk_writes_per_second;    // Disk writes/sec
    uint64_t memory_usage_mb;           // Current memory usage
    time_t last_update_time;            // When metrics were last updated
} system_performance_metrics_t;

// Performance monitor instance
typedef struct {
    perf_monitor_config_t config;       // Configuration
    logger_t* logger;                   // Logger instance
    statistics_collector_t* stats_collector; // Statistics collector
    system_performance_metrics_t metrics;    // Current system metrics
    pthread_mutex_t mutex;              // Thread safety
    bool initialized;                   // Initialization status
    time_t start_time;                  // Monitor start time
    
    // Query tracking
    uint64_t query_counter;             // Total query counter
    uint64_t slow_query_counter;        // Slow query counter
    uint64_t error_counter;             // Error counter
    
    // Performance tracking
    double total_execution_time_ms;     // Total execution time
    double max_execution_time_ms;       // Maximum execution time
    time_t last_metrics_update;         // Last metrics collection time
} perf_monitor_t;

// Global performance monitor
extern perf_monitor_t* g_perf_monitor;

// Lifecycle functions
perf_monitor_t* perf_monitor_create(const perf_monitor_config_t* config);
int perf_monitor_init(perf_monitor_t* monitor, logger_t* logger, 
                     statistics_collector_t* stats_collector);
void perf_monitor_destroy(perf_monitor_t* monitor);
int perf_monitor_set_global(perf_monitor_t* monitor);
perf_monitor_t* perf_monitor_get_global(void);

// Query execution monitoring
query_execution_context_t* perf_monitor_start_query(perf_monitor_t* monitor, 
                                                   const char* query_text,
                                                   const char* username,
                                                   const char* database_name);
void perf_monitor_end_query(perf_monitor_t* monitor, 
                           query_execution_context_t* context,
                           uint64_t rows_examined,
                           uint64_t rows_returned,
                           uint64_t bytes_sent,
                           const char* error_message);
void perf_monitor_free_query_context(query_execution_context_t* context);

// System metrics collection
int perf_monitor_update_metrics(perf_monitor_t* monitor);
int perf_monitor_get_metrics(perf_monitor_t* monitor, 
                            system_performance_metrics_t* metrics);

// Performance monitoring utilities
bool perf_monitor_is_slow_query(perf_monitor_t* monitor, uint64_t execution_time_ms);
void perf_monitor_log_system_status(perf_monitor_t* monitor);
void perf_monitor_log_slow_query_summary(perf_monitor_t* monitor);

// Connection tracking
void perf_monitor_connection_opened(perf_monitor_t* monitor);
void perf_monitor_connection_closed(perf_monitor_t* monitor);

// Cache statistics integration
void perf_monitor_cache_hit(perf_monitor_t* monitor);
void perf_monitor_cache_miss(perf_monitor_t* monitor);

// Disk I/O tracking
void perf_monitor_disk_read(perf_monitor_t* monitor, uint64_t bytes);
void perf_monitor_disk_write(perf_monitor_t* monitor, uint64_t bytes);

// Memory usage tracking
void perf_monitor_update_memory_usage(perf_monitor_t* monitor, uint64_t memory_mb);

// Default configuration
static inline perf_monitor_config_t perf_monitor_default_config(void) {
    perf_monitor_config_t config = {
        .slow_query_threshold_ms = 1000,         // 1 second as per spec
        .enable_query_logging = true,
        .enable_slow_query_logging = true,
        .enable_performance_metrics = true,
        .enable_execution_plans = false,         // Can be expensive
        .metrics_collection_interval_ms = 5000   // 5 seconds
    };
    return config;
}

// Convenience macros for global performance monitor
#define PERF_START_QUERY(query, user, db) \
    (g_perf_monitor ? perf_monitor_start_query(g_perf_monitor, query, user, db) : NULL)

#define PERF_END_QUERY(context, examined, returned, bytes, error) \
    do { if (g_perf_monitor && context) \
        perf_monitor_end_query(g_perf_monitor, context, examined, returned, bytes, error); \
    } while(0)

#define PERF_CONNECTION_OPENED() \
    do { if (g_perf_monitor) perf_monitor_connection_opened(g_perf_monitor); } while(0)

#define PERF_CONNECTION_CLOSED() \
    do { if (g_perf_monitor) perf_monitor_connection_closed(g_perf_monitor); } while(0)

#define PERF_CACHE_HIT() \
    do { if (g_perf_monitor) perf_monitor_cache_hit(g_perf_monitor); } while(0)

#define PERF_CACHE_MISS() \
    do { if (g_perf_monitor) perf_monitor_cache_miss(g_perf_monitor); } while(0)

#define PERF_DISK_READ(bytes) \
    do { if (g_perf_monitor) perf_monitor_disk_read(g_perf_monitor, bytes); } while(0)

#define PERF_DISK_WRITE(bytes) \
    do { if (g_perf_monitor) perf_monitor_disk_write(g_perf_monitor, bytes); } while(0)

#ifdef __cplusplus
}
#endif

#endif // GUDB_PERF_MONITOR_H